/*

 * LayoutHelper.cpp
 *
 *  Created on: Oct 29, 2008
 *      Author: tfannes


#include "LayoutHelper.h"
#include "SideButton.h"
#include "CornerButton.h"
#include "HexagonButton.h"
#include "ElementButton.h"
#include <HexGrid.h>

LayoutHelper::LayoutHelper()
{
}

LayoutHelper::~LayoutHelper()
{
}

QPoint LayoutHelper::hexVectorToXY(const HexVector & position, const QRect & windowRect) const
{
	float fX = position.getX() / 6.0f - (position.getY() + position.getZ()) / 12.0f;
	float fY = (position.getZ() - position.getY()) / 6.0f;

	int x = fX * gridSize.width() / 2 + windowRect.center().x();
	int y = fY * gridSize.height() / 2 + windowRect.center().y();

	return QPoint(x, y);
}

QRect LayoutHelper::calculateHexagonGeometry(const HexVector & position, const QRect & windowRect) const
{
	QPoint pos = hexVectorToXY(position, windowRect);

	return QRect(pos - QPoint(hexagonSize.width() / 2, hexagonSize.height() / 2), hexagonSize);
}

QRect LayoutHelper::calculateCornerGeometry(const HexVector & position, const QRect & windowRect) const
{
	QPoint pos = hexVectorToXY(position, windowRect);

	return QRect(pos - QPoint(cornerSize.width() / 2, cornerSize.height() / 2), cornerSize);
}
QRect LayoutHelper::calculateSideGeometry(const HexVector & position, const QRect & windowRect) const
{
	QPoint pos = hexVectorToXY(position, windowRect);
	int p = HexGrid::CheckSideType(position);

	return QRect(pos - QPoint(sideSize[p].width() / 2, sideSize[p].height() / 2), sideSize[p]);
}

void LayoutHelper::setHexagonLayoutData(HexagonButton * button) const
{
	button->setClickableSurface(&(hexagonPolygon));
	button->setMinimumSize(hexagonSize);
	button->setMaximumSize(hexagonSize);
}

void LayoutHelper::setCornerLayoutData(CornerButton * button) const
{
	button->setClickableRadius(cornerRadius);
	button->setMinimumSize(cornerSize);
	button->setMaximumSize(cornerSize);
}

void LayoutHelper::setSideLayoutData(SideButton * button, const HexVector & position) const
{
	int pos = HexGrid::CheckSideType(position);

	button->setClickableSurface(&(sidePolygon[pos]));
	button->setMinimumSize(sideSize[pos]);
	button->setMaximumSize(sideSize[pos]);
}

void LayoutHelper::setElementLayoutData(ElementButton * button, const HexVector & position) const
{
	HexagonButton * hexBtn = qobject_cast<HexagonButton *> (button);
	CornerButton * corBtn = qobject_cast<CornerButton *> (button);
	SideButton * sidBtn = qobject_cast<SideButton *> (button);
	if (hexBtn != 0) setHexagonLayoutData(hexBtn);
	if (corBtn != 0) setCornerLayoutData(corBtn);
	if (sidBtn != 0) setSideLayoutData(sidBtn, position);
}

unsigned int LayoutHelper::adjustLayoutData(unsigned int proposedHexagonRadius)
{
	int xstep = proposedHexagonRadius / 2;
	int radius = xstep * 2;
	int ystep = (int) (radius * 0.8660254037844386468);
	int width = xstep * 4;
	int height = ystep * 2;

	// total properties
	gridSize = QSize(width, height);

	// hexagon properties
	hexagonSize = QSize(width + 1, height + 1);
	hexagonPolygon.setPoints(6, xstep, 0, xstep * 3, 0, width, ystep, xstep * 3, height, xstep, height, 0, ystep);

	// corner properties
	cornerRadius = radius / 10;
	cornerSize = QSize(radius / 5 + 1, radius / 5 + 1);

	// side properties
	double sideHeight = radius / 12;
	double cos = 0.5;
	double sin = 0.8660254037844385966;
	int largedx = xstep * cos;
	int largedy = xstep * sin;
	int smalldx = sideHeight * sin;
	int smalldy = sideHeight * cos;

	sidePolygon[0].setPoints(4, 0, largedy, smalldx, smalldy + largedy, smalldx + largedx, smalldy, largedx, 0);
	sidePolygon[1].setPoints(4, 0, 0, xstep, 0, xstep, (int) sideHeight, 0, (int) sideHeight);
	sidePolygon[2].setPoints(4, 0, smalldy, largedx, smalldy + largedy, smalldx + largedx, largedy, smalldx, 0);
	sideSize[0] = QSize(smalldx + largedx + 1, smalldy + largedy + 1);
	sideSize[1] = QSize(xstep + 1, sideHeight + 1);
	sideSize[2] = QSize(smalldx + largedx + 1, smalldy + largedy + 1);

	return radius;
}

QVector<HexVector> LayoutHelper::findAllHexagonsInRect(const QRect & rct) const
{
	QVector<HexVector> allHexagons;

	recursiveHexagonFinderInRect(HexVector(0, 0, 0), allHexagons, rct);
	return allHexagons;
}

QVector<HexVector> LayoutHelper::findAllCornersInRect(const QRect & rct) const
{
	return findAllCornersInRect(rct, findAllHexagonsInRect(rct));
}

QVector<HexVector> LayoutHelper::findAllCornersInRect(const QRect & rct, const QVector<HexVector> & hexagonsInRect) const
{
	QVector<HexVector> arCorners;

	for (QVector<HexVector>::const_iterator hex = hexagonsInRect.begin(); hex != hexagonsInRect.end(); hex++)
	{
		for (int i = 0; i < 6; i++)
		{
			HexVector cornerPos = (*hex) + Hexagon::AdjCorners[i];

			if (!arCorners.contains(cornerPos))
				if(rct.intersects(calculateCornerGeometry(cornerPos, rct)))
					// store this corner
					arCorners.push_back(cornerPos);

		}
	}

	return arCorners;
}

QVector<HexVector> LayoutHelper::findAllSidesInRect(const QRect & rct) const
{
	return findAllSidesInRect(rct, findAllHexagonsInRect(rct));
}

QVector<HexVector> LayoutHelper::findAllSidesInRect(const QRect & rct, const QVector<HexVector> & hexagonsInRect) const
{
	QVector<HexVector> arSides;

	for (QVector<HexVector>::const_iterator hex = hexagonsInRect.begin(); hex != hexagonsInRect.end(); hex++)
	{
		for (int i = 0; i < 6; i++)
		{
			HexVector sidePos = (*hex) + Hexagon::AdjSides[i];

			if (!arSides.contains(sidePos))
				if(rct.intersects(calculateSideGeometry(sidePos, rct)))
					// store this corner
					arSides.push_back(sidePos);
		}
	}

	return arSides;
}

void LayoutHelper::recursiveHexagonFinderInRect(const HexVector & position, QVector<HexVector> & foundHexagons, const QRect & rct) const
{
	// check if this hexagon is visible
	QRect hexRect = calculateHexagonGeometry(position, rct);
	if (!rct.intersects(hexRect)) return;

	// add the hexagon to the list of visible hexagons
	foundHexagons.push_back(position);

	// check the 6 surrounding polygons
	for (int i = 0; i < 6; i++)
	{
		HexVector otherPosition = position + Hexagon::AdjHexagons[i];
		if (!foundHexagons.contains(otherPosition)) recursiveHexagonFinderInRect(otherPosition, foundHexagons, rct);
	}
}
*/
